package com.kgc.controller;

import com.kgc.bean.GoodsItemVo;
import com.kgc.bean.OrderInfo;
import com.kgc.bean.OrderInfoVo;
import com.kgc.bean.User;
import com.kgc.config.annotation.RequestPermission;
import com.kgc.config.annotation.RequestUser;
import com.kgc.service.BuyLimitService;
import com.kgc.service.SnapupService;
import com.kgc.constant.SysConstant;
import com.kgc.util.ResultBuildUtil;
import com.kgc.util.ReturnResult;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;

import java.io.IOException;
import java.text.ParseException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Map;
import java.util.UUID;

/**
 * @Author：周申宇 <p>
 * @Date:2021/6/21 10:09
 * <p>
 * @Decription: 抢购: 抢购预热 - 用户登记 - 系统发送短信提醒
 */
@RestController
@Api(tags = "抢购活动")
@Slf4j
public class SnapupController {

    @Autowired
    private SnapupService snapupService;

    @Autowired
    private BuyLimitService buyLimitService;


    @ApiOperation("抢购预热")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "activyId", required = true, value = "活动id")
    })
    @PostMapping("/presale")
    public ReturnResult presale(String activyId) {

        log.info("----抢购预热id为{}", activyId);
        return snapupService.addPresale(Integer.valueOf(activyId))
                ? ResultBuildUtil.success("开始放开本次抢购活动")
                : ResultBuildUtil.fail(SysConstant.SYS_RESP_FAILD_CODE, "抢购放开失败，不能重复放开活动");
    }

    @ApiOperation("展示本次抢购活动")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "activyId", required = true, value = "活动id")
    })
    @ApiResponses({
            @ApiResponse(code = 4001, message = "参数错误"),
            @ApiResponse(code = 1001, message = "请重新登录"),
            @ApiResponse(code = 0000, message = "访问成功")
    })
    @PostMapping("/shouActivity")
    public ReturnResult shouActivity(Integer activyId) throws IOException, ClassNotFoundException {

        log.info("----展示的活动id为{}", activyId);
        log.info("时间{}", snapupService.showPresale(activyId).get("buyLimitActivity"));
        return Boolean.valueOf(snapupService.showPresale(activyId).get("flag").toString())
                ? ResultBuildUtil.success(snapupService.showPresale(activyId))
                : ResultBuildUtil.fail(SysConstant.SYS_RESP_FAILD_CODE, "本次活动不存在");
    }

    @RequestPermission
    @ApiOperation("抢购登记")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "activyId", required = true, value = "活动id")
    })
    @ApiResponses({
            @ApiResponse(code = 1001, message = "请重新登录"),
            @ApiResponse(code = 0000, message = "访问成功"),
            @ApiResponse(code = 9999, message = "重复添加")
    })
    @PostMapping("/addRegUser")
    public ReturnResult addRegUser(@ApiIgnore @RequestUser User user, String activyId) {

        log.info("----当前用户：{},添加抢购活动的时间{}", user.getUserId(), LocalDateTime.now());
        if (null == user) {
            return ResultBuildUtil.fail("1001", "请先登录");
        }
        return snapupService.addRegUser(String.valueOf(user.getUserId()), activyId)
                ? ResultBuildUtil.success("添加成功")
                : ResultBuildUtil.fail(SysConstant.SYS_RESP_FAILD_CODE, "您已经添加过本商品，请不用重复添加");
    }

    /**
     * @Auther: 周申宇
     * <p>
     * @Date: 2021/6/19
     * <p>
     * @Description: 开始抢购
     */

    @RequestPermission
    @ApiOperation("开始抢购")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "buyCount", required = true, value = "购买数量"),
            @ApiImplicitParam(name = "activityId", required = true, value = "活动id")
    })
    @ApiResponses({
            @ApiResponse(code = 1001, message = "请重新登录"),
            @ApiResponse(code = 0000, message = "访问成功"),
            @ApiResponse(code = 8001, message = "商品库存不足"),
            @ApiResponse(code = 9999, message = "重复添加"),
            @ApiResponse(code = 7001, message = "抢购失败，没有添加抢购活动")
    })
    @PostMapping("/buyLimit")
    public ReturnResult buyLimit(@ApiIgnore @RequestUser User user,
                                 GoodsItemVo goodsItemVo,
                                 @RequestParam Integer buyCount,
                                 @RequestParam Integer activityId) throws ParseException {
        // 如果用户没有登录，直接返回失败
        if (user != null) {

            // 判断用户是否添加本次抢购
            if (!buyLimitService.checkUserActivity(user.getUserId(), activityId)) {
                return ResultBuildUtil.fail("7001", "抢购失败,您没有添加抢购活动");
            }
            // 判断抢购日期是否结束
            if (!buyLimitService.checkActivityDate(activityId)) {
                return ResultBuildUtil.fail("7001", "抢购失败,您已经错过本次抢购活动时间");
            }

            // 锁定用户，同一个用户在整个抢购过程中，只能抢购一次
            if (!buyLimitService.lockBuyUser(String.valueOf(user.getUserId()), goodsItemVo.getGoodsId())) {
                log.info("-----用户{},商品{}，只能抢购一次", String.valueOf(user.getUserId()), goodsItemVo.getGoodsId());
                return ResultBuildUtil.fail("9999", "抢购失败，统一个商品，同一个用户只能抢购一次");
            }
            // 校验库存，如果库存不足，直接抢购失败
            if (!buyLimitService.checkProdStock(goodsItemVo.getGoodsId(), buyCount)) {
                log.info("-----商品{}，库存不足", goodsItemVo.getGoodsId());
                return ResultBuildUtil.fail("8001", "商品库存不足");
            }

            // 锁库存，如果当前库存已经被其他用户锁定，不可以继续
            while (true) {
                // 判断库存是否释放，只有拿到库存锁，才可以抢购(防止库存锁释放失败，导致程序中断，切记锁库存加超时时间)
                if (!buyLimitService.isStock(goodsItemVo.getGoodsId())) {
                    break;
                }
            }

            // 模拟生成订单，封装实体参数省略
            String tradeOrderNo = "T" + DateTimeFormatter.ofPattern("yyyyMMddHHmmss").format(LocalDateTime.now()) + UUID.randomUUID().toString().replace("-", "").substring(0, 6);

            // 将订单存入redis
            buyLimitService.setTradeOrderNoToRedis(tradeOrderNo, String.valueOf(user.getUserId()));

            // 调用订单接口，生成订单，发送消息队列，异步处理
//            buyLimitService.createTradeOrder(String.valueOf(user.getUserId()), prodId, tradeOrderNo);
            buyLimitService.createTradeOrder(user, goodsItemVo, buyCount, tradeOrderNo);

            OrderInfo orderInfo = null;
            // 不能 OrderInfoVo orderInfoVo
            OrderInfoVo orderInfoVo = new OrderInfoVo();
            // 等待订单生成成功
            while (true) {
                //
                if (buyLimitService.deleteOrderNoByOrderNo(tradeOrderNo)) {
                    orderInfo = buyLimitService.queryOrderInfoByOrderInfoId(tradeOrderNo);
                    BeanUtils.copyProperties(orderInfo, orderInfoVo);
                    break;
                }
            }

            // 减库存
            buyLimitService.subProStockNum(goodsItemVo.getGoodsId(), buyCount);

            // 释放库存锁
            buyLimitService.unLockProStockLock(goodsItemVo.getGoodsId());

            return ResultBuildUtil.success(orderInfoVo);
        }

        return ResultBuildUtil.fail("1001", "请重新登录");
    }

}
